//---------------------------------------------------------------------------

#include "vcl_stl.h"
#pragma hdrstop

#include "h_base.h"
#include "h_xml.h"
#include "h_global.h"
using namespace h_base;
using namespace h_xml;

#include "t_mainform.h"
#include "t_cpathform.h"

#include "h_g.h"
#include "h_portal.h"
#include "h_i18n.h"
#include "h_scrollingwincontrol.h"
#include "h_critical.h"

#include "t_ganttform.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TGanttForm *GanttForm;
//---------------------------------------------------------------------------
__fastcall TGanttForm::TGanttForm(TComponent* Owner)
   : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TGanttForm::Init()
{
   ScrollingWinControl1 = new HScrollingWinControl(this);

   ScrollingWinControl1->Left = 200;
   ScrollingWinControl1->Top = 200;
   ScrollingWinControl1->Align = alClient;
   ScrollingWinControl1->TabStop = true;
   ScrollingWinControl1->Parent = this;
   Image1 = new TImage(ScrollingWinControl1);
   Image1->Left = 0;
   Image1->Top = 0;
   Image1->Parent = ScrollingWinControl1;
   Image1->OnClick = Image1Click;
   Image1->OnDblClick = Image1DblClick;
   Image1->OnMouseDown = Image1MouseDown;
   Image1->OnMouseMove = Image1MouseMove;
   ComboBoxScale->ItemIndex = 0;
}

void __fastcall TGanttForm::Clear()
{
   EditStartTime->Text = "";
}

void __fastcall TGanttForm::ShowIt()
{
   UTF8String StartTimeStr;
   UTF8String EndTimeStr;

   HBatchIcon *Batch = MainForm->Portal->CurrentBatch;

   Batch->Lock();
   StartTimeStr = FormatDateTime(Batch->OutlineStatus.StartTime);
   EndTimeStr = FormatDateTime(Batch->OutlineStatus.EndTime);
   Batch->Unlock();

   if ( EndTimeStr == "" )
   {
      EndTimeStr = StartTimeStr;
   }

   if ( EditStartTime->Text == "" )
   {
      Image1->Width = 3000;
      Image1->Height = 8000;
      Image1->Canvas->Brush->Color = clWhite;
      Image1->Canvas->FillRect(Image1->ClientRect);
   }

   if ( EditStartTime->Text == "" )
   {
      EditStartTime->Text = StartTimeStr;
      EditEndTime->Text = EndTimeStr;
   }
   else
   {
      TDateTime StartTime;
      TDateTime StartTime2;
      ToDateTime(StartTimeStr, StartTime);
      ToDateTime(EditStartTime->Text, StartTime2);
      if ( StartTime > StartTime2 )
      {
         EditStartTime->Text = StartTimeStr;
         EditEndTime->Text = EndTimeStr;
      }
   }

   ShowModal();
}

//---------------------------------------------------------------------------
void __fastcall TGanttForm::ButtonSaveGanttChartClick(TObject *Sender)
{
   SaveDialog1->DefaultExt = "bmp";
   SaveDialog1->FileName = "";
   SaveDialog1->Filter =
      "Bit map file (*.bmp)|*.bmp";
   SaveDialog1->FilterIndex = 1;
   SaveDialog1->InitialDir = h_g::BaseDir + "bats";
   SaveDialog1->Options = TOpenOptions() << ofOverwritePrompt
      << ofPathMustExist << ofEnableSizing;
   SaveDialog1->Title = UTF8String(h_g::I18nString("t_ganttform:SAVE_GANTT_AS"));

   if( !SaveDialog1->Execute() )
      return;

   char TmpStr[500 + 1];
   TRect Rect(0, 0, Image1->Width, Image1->Height);
   TPicture *Pic = new TPicture();

   Pic->Bitmap->Width = Image1->Width;
   Pic->Bitmap->Height = Image1->Height;
   Pic->Bitmap->Canvas->CopyRect(Rect, Image1->Canvas, Rect);
   Pic->SaveToFile(SaveDialog1->FileName);
   delete(Pic);
   snprintf(TmpStr, 500, h_g::I18nString("t_ganttform:GANTT_SAVED"), SaveDialog1->FileName.c_str());
   h_g::ShowMessage(UTF8String(TmpStr));
   ScrollingWinControl1->SetFocus();
}
//---------------------------------------------------------------------------

static bool operator<(const HGanttInfo &lhs, const HGanttInfo &rhs)
{
   if ( lhs.StartFlag && !rhs.StartFlag )
   {
      return true;
   }

   if ( !lhs.StartFlag && rhs.StartFlag )
   {
      return false;
   }

   if ( lhs.StartTime < rhs.StartTime )
   {
      return true;
   }

   if ( lhs.StartTime > rhs.StartTime )
   {
      return false;
   }

   return lhs.Name < rhs.Name;
}

void __fastcall TGanttForm::ButtonDrawGanttChartClick(TObject *Sender)
{
   UTF8String StartTimeStr = EditStartTime->Text.TrimRight();
   UTF8String EndTimeStr = EditEndTime->Text.TrimRight();
   TDateTime StartTime;
   TDateTime EndTime;
   TDateTime RulerStartTime;
   TDateTime RulerEndTime;
   unsigned short Hour;
   unsigned short Min;
   unsigned short Sec;
   unsigned short MSec;
   int Scale = ComboBoxScale->ItemIndex * 5;

   if ( Scale == 0 )
   {
      Scale = 1;
   }

   if ( !ToDateTime(StartTimeStr, StartTime) ||
        !ToDateTime(EndTimeStr, EndTime) )
   {
      h_g::ShowMessage(UTF8String(h_g::I18nString("t_ganttform:TIME_FORMAT_ERROR")));
      return;
   }

   if ( DateTimeToSec(EndTime - StartTime) > 24 * 3600 )
   {
      h_g::ShowMessage(UTF8String(h_g::I18nString("t_ganttform:TIME_RANGE_ERROR")));
      return;
   }

   GanttVec.clear();
   CriticalSet.clear();

   if ( CheckBoxCritical->Checked )
   {
      MainForm->SaveToJobList(JobMap, true);
      HCritical Critical(JobMap);
      set<UTF8String> ExcludeSet;
      CpathForm->GetExcludeList(ExcludeSet);
      vector<HJobListInfo*> JobVec;
      Critical.Calculate(JobVec, ExcludeSet);
      for ( int i = 0; i < JobVec.size(); i++ )
      {
         CriticalSet.insert(JobVec[i]->Name);
      }
   }

   MainForm->SaveToGanttList(StartTime, EndTime,
      CheckBoxPartitionedJobOnly->Checked, EditTime->Text.ToIntDef(0), GanttVec);
   sort(GanttVec.begin(), GanttVec.end());
   StartTime.DecodeTime(&Hour, &Min, &Sec, &MSec);
   RulerStartTime = StartTime;

   if ( Sec > 0 )
   {
      RulerStartTime -= TDateTime(0, 0, Sec, 0);
   }

   RulerEndTime = EndTime;
   ( RulerEndTime - RulerStartTime ).DecodeTime(&Hour, &Min, &Sec, &MSec);

   int TotalSec = Hour * 60 * 60 + Min * 60 + Sec;

   if ( TotalSec % ( 60 * Scale ) != 0 )
   {
      Sec = 60 * Scale - TotalSec % ( 60 * Scale );
      TotalSec += Sec;
      Min = Sec / 60;
      Sec = Sec % 60;
      RulerEndTime += TDateTime(0, Min, Sec, 0);
   }

   Image1->Width = ( TotalSec / Scale + 150 ) * 2;
   Image1->Height = ( RulerTop + GanttVec.size() * 15 + 15 ) * 2;

   if ( Image1->Width < ClientWidth - 2 )
   {
      Image1->Width = ClientWidth - 2;
   }

   if ( Image1->Height < ClientHeight - Panel1->Height - 2 )
   {
      Image1->Height = ClientHeight - Panel1->Height - 2;
   }

   if ( Image1->Width > 3000 )
   {
      Image1->Width = 3000;
   }

   if ( Image1->Height > 8000 )
   {
      Image1->Height = 8000;
   }

   Image1->Canvas->Brush->Color = clWhite;
   Image1->Canvas->FillRect(Image1->ClientRect);
   Image1->Canvas->Pen->Color = (TColor)RGB(220, 220, 220);
   Image1->Canvas->Pen->Style = psDot;

   for ( int i = 0; i <= TotalSec; i += 30 * Scale )
   {
      Image1->Canvas->MoveTo(( RulerLeft + i / Scale ) * 2, RulerTop * 2);
      Image1->Canvas->LineTo(( RulerLeft + i / Scale ) * 2, Image1->Height);
   }

   Image1->Canvas->Pen->Color = clBlack;
   Image1->Canvas->Pen->Style = psSolid;
   Image1->Canvas->MoveTo(RulerLeft * 2, RulerTop * 2);
   Image1->Canvas->LineTo(( RulerLeft + TotalSec / Scale ) * 2, RulerTop * 2);

   for ( int i = 0; i <= TotalSec; i += 30 * Scale )
   {
      Image1->Canvas->MoveTo(( RulerLeft + i / Scale ) * 2, RulerTop * 2);
      Image1->Canvas->LineTo(( RulerLeft + i / Scale ) * 2,
         ( RulerTop + ( i / ( 30 * Scale ) % 2 == 0 ? 10 : 5 ) ) * 2);
   }

   RulerStartTime.DecodeTime(&Hour, &Min, &Sec, &MSec);
   Image1->Canvas->Font->Name = UTF8String(h_g::I18nString("t_ganttform:FONT_NAME"));
   Image1->Canvas->Font->Size = 16;

   for ( int i = 0; i <= TotalSec; i += 60 * Scale )
   {
      char TmpStr[200 + 1];
      snprintf(TmpStr, 200, "%02d:%02d", Hour, Min);
      Image1->Canvas->TextOut(( RulerLeft + i / Scale - 15 ) * 2,
         ( RulerTop - 15 ) * 2, UTF8String(TmpStr));
      Min += Scale;
      if ( Min >= 60 )
      {
         Min = 0;
         Hour++;
         if ( Hour >= 24 )
         {
            Hour = 0;
         }
      }
   }

#ifdef SIMBAT_ENTERPRISE
   ButtonDrawGanttChartClick_aux(RulerStartTime, Scale);
#endif

   ScrollingWinControl1->SetFocus();
}
//---------------------------------------------------------------------------

void __fastcall TGanttForm::Image1Click(TObject *Sender)
{
   ScrollingWinControl1->SetFocus();
}

void __fastcall TGanttForm::Image1DblClick(TObject *Sender)
{
   int X = LastX;
   int Y = LastY;

   int i = ( Y / 2 - RulerTop - 15 ) / 15;

   if ( i < 0 || i >= GanttVec.size() )
   {
      return;
   }

   HGanttInfo &Info = GanttVec[i];

   if ( X >= Info.Left && X <= Info.Right )
   {
      MainForm->GotoGroupAndFocusToJob(Info.Name);
      Close();
   }
}

void __fastcall TGanttForm::Image1MouseDown(TObject* Sender, TMouseButton Button,
   TShiftState Shift, int X, int Y)
{
   LastX = X;
   LastY = Y;
}

void __fastcall TGanttForm::Image1MouseMove(TObject *Sender,
   TShiftState Shift, int X, int Y)
{
   int i = ( Y / 2 - RulerTop - 15 ) / 15;

   if ( i < 0 || i >= GanttVec.size() )
   {
      Image1->ShowHint = false;
      return;
   }

   HGanttInfo &Info = GanttVec[i];

   if ( X >= Info.Left && X <= Info.Right )
   {
      Image1->Hint = Info.Hint;
      Image1->ShowHint = true;
   }
   else
   {
      Image1->ShowHint = false;
   }
}

